package com.qf.openapi.web.master.service.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qf.openapi.web.master.dao.UserDao;
import com.qf.openapi.web.master.entity.User;
import com.qf.openapi.web.master.service.UserService;
import com.qf.openapi.web.master.utils.Constants;

import com.qf.openapi.web.master.utils.FileAppender;
import com.qf.openapi.web.master.vo.PageVo;
import com.qf.openapi.web.master.vo.ResultVo;
import com.qf.openapi.web.master.vo.TableVo;
import com.qf.openapi.web.master.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service("userService")
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    UserDao userDao;

    //检查用户姓名
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public ResultVo checkUserName(String username) {
        ResultVo resultVo = null;
        final User user = userDao.getUserByName(username);
        if(username==""){
            resultVo = ResultVo.fail();
        }else
        if (user!=null){
            resultVo = ResultVo.fail();
        }else {
            resultVo = ResultVo.ok();
        }
        return resultVo;
    }


    @Override
    public User getUserById(Integer id) {
        log.debug("传入用户的id值为 {} ", id);
        final User user = userDao.getUserById(id);
        log.debug("查询到的用户名{}，用户性别{}",user.getName(),user.getSex());
        return user;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public User login(String username, String password) {
        log.debug("方法入参为username={}，password={}",username,password);
        //1 .根据用户名去数据库中查询用户信息
        User user = userDao.getUserByName(username);
        //2. 如果user为null，则直接返回，如果不为null，则继续判断密码是否一直
        if (user!=null){
            final String dbpassword = user.getPassword();
            if(!dbpassword.equals(password)){
                user = null;
            }
        }
        return user;
    }

    //分页查询
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public TableVo<User> getAllUsersByPage(PageVo pageVo, UserVo userVo) {
        PageHelper.startPage(pageVo.getPage(),pageVo.getLimit());
        final List<User> users = userDao.getAllUsersByCondition(userVo);
        final PageInfo<User> pageInfo = new PageInfo<>(users);
        log.debug("查询到的分页数据为{}",pageInfo);
        return TableVo.ok(pageInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultVo regist(UserVo userVo, MultipartFile file1, String realPath) {
        ResultVo resultVo = null;
        try {
            //1. 存放图片文件到指定的位置
            //1.1 生成文件名
            final String randomName = UUID.randomUUID().toString();
            final String originalFilename = file1.getOriginalFilename();
            final String extension = FilenameUtils.getExtension(originalFilename);
            String finalFileName = randomName+"."+ extension;
            String finalFilePath = realPath+ File.separator+finalFileName;
            log.debug("用户头像存放的路径为{}",finalFilePath);
            file1.transferTo(new File(finalFilePath));
            //2. 把用户信息保存到数据库中
            final User user = new User();
            // 利用spring的bean工具类实现属性拷贝
            BeanUtils.copyProperties(userVo,user);
            user.setFilepath(finalFileName);
            user.setRegistTime(new Date());
            // 写入数据库
            log.debug("写入数据库的注册的用户信息为{}",user);
            userDao.insertUser(user);
            //3. 封装ResultVo对象并返回
            resultVo = ResultVo.ok(user);
        }catch (Exception e){
            e.printStackTrace();
            resultVo = ResultVo.fail();
        }
        return resultVo;
    }

    @Override
    public ResultVo exportBatch(String realPath) {
        ResultVo resultVo = null;
        // 生成最终的文件名
        final String s = UUID.randomUUID().toString();
        final String finalFilename = s+ ".csv";
        try {
            // 获取user表的数据总量
            Integer count  =  userDao.getTotalCount();
            final FileAppender fileAppender = new FileAppender(realPath + File.separator + finalFilename);
            // 计算导出的次数
            Integer times = count%Constants.EXPORT_PAGE_LIMIT==0?count/Constants.EXPORT_PAGE_LIMIT:count/Constants.EXPORT_PAGE_LIMIT+1;
            for (int i=0;i<times;i++){
                PageHelper.startPage(i+1,Constants.EXPORT_PAGE_LIMIT);
                final List<User> users = userDao.getAllUsers();
                final List<String> data = users.stream().map(user -> user.toCSVString()).collect(Collectors.toList());
                fileAppender.append(data);
            }
            fileAppender.close();
            resultVo = ResultVo.ok(finalFilename);
        }catch (Exception e){
            e.printStackTrace();
            resultVo = ResultVo.fail();
        }
        return resultVo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultVo addUser(User user) {
        try {
            final String name = user.getName();
            final User userByName = userDao.getUserByName(name);
            if (userByName != null) { //校验用户名是否存在
                return ResultVo.failWithErrorMsg(Constants.USER_NAME_EXIST_ERROR_MSG);
            }
            //向数据库表中添加用户
            final String password = user.getPassword();
            if (password == null || password.equals("")) {
                return ResultVo.failWithErrorMsg(Constants.USER_PASSWORD_ERROR_MSG);
            }
            userDao.insertUser(user);
        }catch (Exception e){
            e.printStackTrace();
            return ResultVo.failWithErrorMsg(Constants.USER_REGIST_ERROR_MSG);
        }
        //封装user对象
        return ResultVo.ok();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultVo del(String[] ids) {
        ResultVo resultVo = null;
        // 判断数组长度是否为0,若为0说明取到值,可以删除
        if(ids.length>0){
            userDao.deleteUserByIds(ids);
            resultVo = ResultVo.ok();
        }else {
            resultVo = ResultVo.failWithErrorMsg(Constants.USER_IDS_LENGHT_ERROR_MSG);
        }
        return resultVo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultVo updateUser(User user) {
        ResultVo resultVo = null;
        // 校验id是否为空
        final Integer id = user.getId();
        if (id==null){
            resultVo = ResultVo.fail();
        }else {
            userDao.updateUser(user);
            resultVo = ResultVo.ok();
        }
        return resultVo;
    }

}
